package com.crx.springbootinit.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crx.springbootinit.model.dto.comment.CommentDto;
import com.crx.springbootinit.model.dto.comment.CommentPostIdPageDTO;
import com.crx.springbootinit.model.dto.comment.CommentsPageDTO;
import com.crx.springbootinit.model.dto.page.PageVO;
import com.crx.springbootinit.model.entity.Comment;
import com.crx.springbootinit.mapper.CommentMapper;
import com.crx.springbootinit.model.entity.Post;
import com.crx.springbootinit.model.entity.User;
import com.crx.springbootinit.model.vo.comment.CommentChildrenVO;
import com.crx.springbootinit.model.vo.comment.CommentPageVO;
import com.crx.springbootinit.model.vo.comment.CommentsVO;
import com.crx.springbootinit.model.vo.comment.NoticeCommentVO;
import com.crx.springbootinit.model.vo.follow.FollowPageVo;
import com.crx.springbootinit.service.ICommentLoveService;
import com.crx.springbootinit.service.ICommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crx.springbootinit.service.IPostService;
import com.crx.springbootinit.service.IUserService;
import com.crx.springbootinit.utils.ThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 评论表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-10-21
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private IPostService postService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICommentLoveService commentLoveService;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 新增评论
     *
     * @param commentDto 评论请求对象
     * @return 成功消息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommentChildrenVO addComment(CommentDto commentDto) {
        Long userId = ThreadLocalUtil.get("userId");
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDto, comment);
        comment.setCreateTime(LocalDateTime.now());
        comment.setUserId(userId);
        commentMapper.insert(comment);
        CommentChildrenVO commentChildrenVO = new CommentChildrenVO();
        BeanUtils.copyProperties(comment, commentChildrenVO);
        User userServiceById = userService.getById(userId);
        commentChildrenVO.setAvatar(userServiceById.getAvatar());
        commentChildrenVO.setNickName(userServiceById.getNickname());
        commentChildrenVO.setIsCommentLove(false);
        commentChildrenVO.setLoveCount(0L);
        if(comment.getParentId() != 0){
            Long userId1 = commentMapper.selectById(comment.getParentId()).getUserId();
            User userServiceById1 = userService.getById(userId1);
            commentChildrenVO.setCommentedUserName(userServiceById1.getNickname());
        }
        postService.update(null,
                new UpdateWrapper<Post>()
                        .eq("id", commentDto.getPostId()) // 条件：指定帖子
                        .setSql("comment_count = comment_count + 1") // 字段加 1
        );
        return commentChildrenVO;
    }

    /**
     * 获取评论列表
     *
     * @return 评论列表
     */
    @Override
    public PageVO<CommentsVO> getCommentListByPostId(String token,CommentPostIdPageDTO commentPostIdPageDTO) {
        Long userId = new Long(0);
        if(!StringUtils.isEmpty(token)){
            userId = (Long) redisTemplate.opsForValue().get(token);
        }
        PageVO<CommentsVO> pageVO = new PageVO<>();
        int offset = (commentPostIdPageDTO.getPageNo() - 1) * commentPostIdPageDTO.getPageSize();
        List<CommentsVO> commentsVOList = commentMapper.getAllRoot(commentPostIdPageDTO.getPostId(), commentPostIdPageDTO.getPageSize(), offset);
        // 4.遍历commentsVOList列表，添加对应的子评论（二级评论在一级评论的children字段中，三级评论在二级评论的children字段中，以此类推）
        for (CommentsVO comment : commentsVOList) {
            // 调用查询子评论的方法，需要该顶级评论自己的 id 与 关联主体 id
            // 【注意】这里就用到了vo中最后一个子评论列表 private List<CommentsVO> children 字段，设置子孩子的时候也是按照CommentsVO类型来返回数据的
            comment.setChildren(getChildrenComments(userId,comment.getId(), commentPostIdPageDTO.getPostId(),5,0));
            Boolean commentLove = commentLoveService.isCommentLove(userId, comment.getId());
            comment.setIsCommentLove(commentLove);
        }
        Long totalRecords = new Long(commentMapper.getAllRootTotalCount(commentPostIdPageDTO.getPostId()));
        Long totalPages = (totalRecords + commentPostIdPageDTO.getPageSize() - 1) / commentPostIdPageDTO.getPageSize();

        pageVO.setPages(totalPages);
        pageVO.setTotal(totalRecords);
        pageVO.setList(commentsVOList);
        return pageVO;
    }

    @Override
    public PageVO<NoticeCommentVO> getNoticeCommentList(int pageNum, int pageSize) {
        Long userId = ThreadLocalUtil.get("userId");
        PageVO<NoticeCommentVO> pageVO = new PageVO<>(0L,0L,null);
        List<NoticeCommentVO> noticeCommentVOList = new ArrayList<>();
        // 1. 查询你的所有评论
        List<Comment> myComments = findMyComments(userId);

        // 如果用户没有评论，直接返回空分页
        if (myComments.isEmpty()) {
            return pageVO;
        }

        // 2. 查找所有回复你的评论，分页查询
        List<Long> myCommentIds = new ArrayList<>();
        for (Comment comment : myComments) {
            myCommentIds.add(comment.getId());
        }

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Comment::getParentId, myCommentIds);  // parentId在你的评论ID列表中
        queryWrapper.orderByDesc(Comment::getCreateTime);  // 按照创建时间降序排列

        // 分页查询
        Page<Comment> page = new Page<>(pageNum, pageSize);
        Page<Comment> resultPage = commentMapper.selectPage(page, queryWrapper);
        for (Comment record : resultPage.getRecords()) {
            NoticeCommentVO noticeCommentVO = new NoticeCommentVO();
            noticeCommentVO.setId(record.getUserId());
            noticeCommentVO.setContent(record.getContent());
            Post postById = postService.getById(record.getPostId());
            User userById = userService.getById(record.getUserId());
            noticeCommentVO.setNickname(userById.getNickname());
            noticeCommentVO.setAvatar(userById.getAvatar());
            String imageListStr = postById.getImageList();  // 获取图片列表字符串
            if (imageListStr != null && !imageListStr.isEmpty()) {
                // 使用 Fastjson 解析 JSON 字符串为 List<String>
                List<String> imageList = JSON.parseArray(imageListStr, String.class);
                noticeCommentVO.setImageUrl(imageList.get(0));  // 设置到 PostHomeVO 中
            }
            noticeCommentVO.setCreateTime(record.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM")));
            noticeCommentVOList.add(noticeCommentVO);
        }
        pageVO.setTotal(resultPage.getTotal());
        pageVO.setPages(resultPage.getPages());
        pageVO.setList(noticeCommentVOList);
        return pageVO;
    }

    /**
     * 获取子评论的方法
     *
     * @param parentId
     * @param momentId
     * @return
     */
    @Override
    public PageVO<CommentChildrenVO> getChildrenComments(Long userId,long parentId, long momentId, int pageSize, int offset) {
        PageVO<CommentChildrenVO> pageVO = new PageVO<>();
        // 查所有的子评论（需要的是该子评论的直接父评论ID，一开始从二级评论开始查，也就是调用此方法时传进来的顶级评论id[这就是二级评论的直接父评论ID]；还有关联主体id）
        List<CommentChildrenVO> commentsVOList = commentMapper.getRootCommentId(parentId, momentId,pageSize,offset);
        for (CommentChildrenVO comment : commentsVOList){
            Comment byId = getById(comment.getParentId());
            User userServiceById = userService.getById(byId.getUserId());
            comment.setCommentedUserName(userServiceById.getNickname());
            Boolean commentLove = commentLoveService.isCommentLove(userId, comment.getId());
            comment.setIsCommentLove(commentLove);
        }
        // 遍历名为commentsVOList的CommentsVO类型的集合
//        for (CommentsVO comment : commentsVOList) {
//            // 此处用到了递归，递归查询每一级评论，每次调用本层的id去查子一层
//            // 【注意】每一个子孩子还有子孩子的话，也是按照CommentsVO类型来存放
//            comment.setChildren(getChildrenComments(comment.getId(), momentId,pageSize,offset));
//        }
        Long totalRecords = new Long(commentMapper.getRootCommentIdTotalCount(momentId,parentId));
        Long totalPages = (totalRecords + pageSize - 1) / pageSize;

        pageVO.setPages(totalPages);
        pageVO.setTotal(totalRecords);
        pageVO.setList(commentsVOList);
        return pageVO;
    }

    @Override
    public PageVO<CommentPageVO> queryCommentPage(CommentsPageDTO commentsPageDTO) {
        Page<CommentPageVO> page = new Page<>(commentsPageDTO.getPageNo(), commentsPageDTO.getPageSize());
        IPage<CommentPageVO> commentIPage=baseMapper.queryCommentPage(page,commentsPageDTO);
        PageVO<CommentPageVO> commentPageVO = new PageVO<>();
        commentPageVO.setList(commentIPage.getRecords());
        commentPageVO.setPages(commentIPage.getPages());
        commentPageVO.setTotal(commentIPage.getTotal());
        return commentPageVO;
    }

    // 查询你所有的评论
    public List<Comment> findMyComments(Long userId) {
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getUserId, userId);  // 筛选用户的所有评论
        return commentMapper.selectList(queryWrapper);
    }
}
